#include "MainWindow.h"

#include <QGraphicsDropShadowEffect>
#include <QDebug>

#include "Controller.h"
#include "CommandFactory.h"
#include "EncryptWidget.h"
#include "DecryptWidget.h"
#include "KeyManagerWidget.h"

using namespace kryptos::controller;

namespace kryptos { namespace ui {

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint)
{
    ui.setupUi(this);

    move(500, 100);

    setAttribute(Qt::WA_TranslucentBackground,true);

    QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(this);
    shadow->setBlurRadius(14.0);
    shadow->setXOffset(0);
    shadow->setYOffset(0);
    shadow->setColor(Qt::black);
    ui.wContainer->setGraphicsEffect(shadow);

    ui.wMiddle->hide();
    m_originalSize = size();
    m_containerOriginalSize = ui.wContainer->size();

    m_menuButtonGroup.addButton(ui.bEncrypt, Encrypt);
    m_menuButtonGroup.addButton(ui.bDecrypt, Decrypt);
    m_menuButtonGroup.addButton(ui.bDelete, Delete);
    m_menuButtonGroup.addButton(ui.bKeyManager, KeyManager);

    m_firstShow = true;

    connect(&Controller::instance(), SIGNAL(showApplication())            , this, SLOT(bringToFront()));
    connect(&Controller::instance(), SIGNAL(hideApplication())            , this, SLOT(hide()));
    connect(&Controller::instance(), SIGNAL(encryptionOperationFinished()), this, SLOT(hideActionWidget()));

    connect(&m_menuButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(actionSelected(int)));
}

void MainWindow::bringToFront()
{
    show();
    raise();
    activateWindow();

    Controller::instance().viewIsReady();
}

void MainWindow::actionSelected(int action)
{
    if (m_activeAction != action)
    {
        switch (action)
        {
            case Encrypt: createActionWidget<EncryptWidget>(QSize(m_containerOriginalSize.width(), 500)); initEncryptionWidget(); break;
            case Decrypt: createActionWidget<DecryptWidget>(QSize(m_containerOriginalSize.width(), 300)); initDecryptionWidget(); break;
            case KeyManager: createActionWidget<KeyManagerWidget>(QSize(m_containerOriginalSize.width(), 550)); initKeyManagerWidget(); break;
        }

        m_currentActionWidget->show();
        ui.wMiddle->show();
        m_activeAction = (ActionType)action;
    }
    else
    {
        hideActionWidget();
    }
}

void MainWindow::hideActionWidget()
{
    // Hack to be able to leave every button in QButtonGroup unchecked
    m_menuButtonGroup.setExclusive(false);
    qDebug() << m_activeAction;
    m_menuButtonGroup.button(m_activeAction)->setChecked(false);
    m_menuButtonGroup.setExclusive(true);

    m_activeAction = (ActionType)-1;
    ui.wMiddle->layout()->removeWidget(m_currentActionWidget.data());
    ui.wMiddle->hide();
    m_currentActionWidget->hide();
    ui.wContainer->resize(m_containerOriginalSize);
    resize(m_originalSize);
}

template<class T> void MainWindow::createActionWidget(QSize size)
{
    if (!m_currentActionWidget.isNull())
    {
        ui.wMiddle->layout()->removeWidget(m_currentActionWidget.data());
        ui.wMiddle->hide();
        m_currentActionWidget->hide();
    }

    m_currentActionWidget.reset(new T(this));
    m_currentActionWidget->resize(size);

    ui.wMiddle->layout()->addWidget(m_currentActionWidget.data());

    ui.wContainer->resize(size.width(), m_containerOriginalSize.height() + size.height());
    resize(width(), height() + size.height());
}

void MainWindow::initEncryptionWidget()
{
    EncryptWidget* encryptWidget = qobject_cast<EncryptWidget*>(m_currentActionWidget.data());
    if (encryptWidget)
    {
        encryptWidget->setEncryptCommand(&CommandFactory::buildEncryptCommand());
        encryptWidget->fillContactsList(Controller::instance().contacts());
        encryptWidget->init();
    }
}

void MainWindow::initDecryptionWidget()
{
    DecryptWidget* decryptWidget = qobject_cast<DecryptWidget*>(m_currentActionWidget.data());
    if (decryptWidget)
    {
        decryptWidget->setDecryptCommand(&CommandFactory::buildDecryptCommand());
        decryptWidget->init();
    }
}

void MainWindow::initKeyManagerWidget()
{
    KeyManagerWidget* keyManagerWidget = qobject_cast<KeyManagerWidget*>(m_currentActionWidget.data());
    if (keyManagerWidget)
    {
        keyManagerWidget->setCreateKeyCommand(&CommandFactory::buildCreateKeyCommand());
        keyManagerWidget->setShareKeyCommand(&CommandFactory::buildShareKeyCommand());
        //keyManagerWidget->init();
    }
}

}}
